home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Int64.h
-
- Contains: xxx put contents here xxx
-
- Written by: xxx put writers here xxx
-
- Copyright: © 1994-1995 by Apple Computer, Inc., all rights reserved.
-
- <2> 3/20/95 andy
- */
-
- #ifndef Int64_h
- #define Int64_h
-
- #ifndef REZ
-
- //
- // For SInt64
- //
- #include <Types.h>
-
- // •ga
- #define typeInt64 'in64'
-
- class TIcon;
- class Int64;
-
- enum
- {
- kInt64CanNotFitIn32Bits = 0x7FFFFFFF,
-
- kRemoveSize = true,
- kDontRemoveSize = false,
-
- typeOtherIsInt64 = 0,
- typeOtherIsInt = 128,
- typeOtherIsULong = 64,
- typeOtherIsLong = 32,
- typeMask = typeOtherIsInt64 | typeOtherIsInt | typeOtherIsULong | typeOtherIsLong,
-
- verbMask = 0xF,
- verbAdd = 0,
- verbSubtract = 1,
- verbMultiply = 2,
- verbDivide = 3,
- verbShiftRight = 4,
- verbShiftLeft = 5,
- verbBitAnd = 6,
- verbAssign = 8,
-
-
- cmpMask = verbMask,
- cmpNotEqual = 0,
- cmpEqual = 1,
- cmpGreaterOrEqual = 2,
- cmpLess = 3,
- cmpLessOrEqual = 4,
- cmpGreater = 5,
-
- opAssignInt64 = verbAssign | typeOtherIsInt64,
- opAddInt64 = verbAdd | typeOtherIsInt64,
- opSubtractInt64 = verbSubtract | typeOtherIsInt64,
- opMultiplyInt64 = verbMultiply | typeOtherIsInt64,
- opDivideInt64 = verbDivide | typeOtherIsInt64,
- opShiftRightInt64 = verbShiftRight | typeOtherIsInt64,
- opShiftLeftInt64 = verbShiftLeft | typeOtherIsInt64,
-
- opAssignLong = verbAssign | typeOtherIsLong,
- opAddLong = verbAdd | typeOtherIsLong,
- opSubtractLong = verbSubtract | typeOtherIsLong,
- opMultiplyLong = verbMultiply | typeOtherIsLong,
- opDivideLong = verbDivide | typeOtherIsLong,
- opShiftRightLong = verbShiftRight | typeOtherIsLong,
- opShiftLeftLong = verbShiftLeft | typeOtherIsLong,
-
- opAssignUnsignedLong = verbAssign | typeOtherIsULong,
- opAddUnsignedLong = verbAdd | typeOtherIsULong,
- opSubtractUnsignedLong = verbSubtract | typeOtherIsULong,
- opMultiplyUnsignedLon = verbMultiply | typeOtherIsULong,
- opDivideUnsignedLong = verbDivide | typeOtherIsULong,
-
- opAssignInt = verbAssign | typeOtherIsInt,
- opAddInt = verbAdd | typeOtherIsInt,
- opSubtractInt = verbSubtract | typeOtherIsInt,
- opMultiplyInt = verbMultiply | typeOtherIsInt,
- opDivideInt = verbDivide | typeOtherIsInt,
-
- cmpNotEqualInt64 = cmpNotEqual | typeOtherIsInt64,
- cmpEqualInt64 = cmpEqual | typeOtherIsInt64,
- cmpGreaterOrEqualInt64 = cmpGreaterOrEqual | typeOtherIsInt64,
- cmpLessInt64 = cmpLess | typeOtherIsInt64,
- cmpLessOrEqualInt64 = cmpLessOrEqual | typeOtherIsInt64,
- cmpGreaterInt64 = cmpGreater | typeOtherIsInt64,
-
- cmpNotEqualLong = cmpNotEqual | typeOtherIsLong,
- cmpEqualLong = cmpEqual | typeOtherIsLong,
- cmpGreaterOrEqualLong = cmpGreaterOrEqual | typeOtherIsLong,
- cmpLessLong = cmpLess | typeOtherIsLong,
- cmpLessOrEqualLong = cmpLessOrEqual | typeOtherIsLong,
- cmpGreaterLong = cmpGreater | typeOtherIsLong,
-
- cmpNotEqualUnsignedLong = cmpNotEqual | typeOtherIsULong,
- cmpEqualUnsignedLong = cmpEqual | typeOtherIsULong,
- cmpGreaterOrEqualUnsignedLong= cmpGreaterOrEqual | typeOtherIsULong,
- cmpLessUnsignedLong = cmpLess | typeOtherIsULong,
- cmpLessOrEqualUnsignedLong = cmpLessOrEqual | typeOtherIsULong,
- cmpGreaterUnsignedLong = cmpGreater | typeOtherIsULong
- };
-
- // I used my own defin here in so that all of the math is based on
- // the one assumption of 32 bit longs. Didn't want this to partially
- // work for other sizes.
- #define MAXULONG ((2 ^ 32) - 1)
-
- //
- // Old versions of Types.h use 'wide' instead of 'SInt64'
- // (the #ifndef doesn't seem to work, but the redefinition is okay;
- // I left the #ifndef in for clarity.)
- //
- #ifndef SInt64
- typedef wide SInt64;
- #endif
-
-
- //========================================================================================
- // CLASS Int64
- //
- // int is the natural type for the value 0 {ARM, pg 324}, so TWide
- // has a number of conversion operators from integer types so that
- // there is never any ambiguity {upon which the compiler would barf!}.
- //
- // For instance, if there were no TWide(int) the compiler would try to
- // match “TWide aWide = 0;” with both TWide(long) and TWide(unsigned long),
- // both of which are conversions, yielding an ambiguous state.
- //========================================================================================
-
- class Int64
- {
-
- //
- // --- Methods -------------------------------------------------------------------------------------
- //
- public:
- Int64();
- Int64(int i);
- Int64(SInt32 l);
- Int64(UInt32 l);
- Int64(UInt32 high,UInt32 low);
- Int64(SInt64);
-
- operator SInt32() const;
- operator UInt32() const;
- operator double() const;
-
- UInt32 High32();
- UInt32 Low32();
-
- Int64& operator =(const Int64&);
- Int64& operator =(int); // to convert from zero
- Int64& operator =(SInt32); // to convert non-zero signed values
- Int64& operator =(UInt32); // to convert non-zero unsigned values
- Int64& operator =(SInt64);
-
- Int64 operator +(const Int64&) const;
- Int64 operator -(const Int64&) const;
- Int64 operator *(const Int64&) const;
- Int64 operator /(const Int64&) const;
- Int64 operator >>(const Int64&) const;
- Int64 operator <<(const Int64&) const;
-
- //
- // Because of the way Int64's are passed around and made into temporaries these
- // “operate and assign” functions are more efficient than the above ones.
- //
- Int64& operator +=(const Int64&);
- Int64& operator -=(const Int64&);
- Int64& operator >>=(const Int64&);
- Int64& operator <<=(const Int64&);
- Int64& operator *=(const Int64&);
- Int64& operator &=(const Int64&);
-
- Boolean operator !=(const Int64&) const;
- Boolean operator ==(const Int64&) const;
- Boolean operator >=(const Int64&) const;
- Boolean operator <(const Int64&) const;
- Boolean operator <=(const Int64&) const;
- Boolean operator >(const Int64&) const;
-
- operator SInt64() { return fSInt64; }
-
- Boolean FitsInLong() const;
- Boolean FitsInUnsignedLong() const;
-
- protected:
- static const Int64* IntuitOtherOperand(SInt16 operation, const void* other, Int64* storage);
- Int64 Operation(SInt16 operation, const void* other) const;
- Boolean Comparison(SInt16 comparison, const void* otherP) const;
-
- //
- // --- Fields -------------------------------------------------------------------------------------
- //
- SInt64 fSInt64;
- };
-
- //inline Boolean operator < (SInt32 l, const Int64& i64) { return (i64 > l); }
-
- inline UInt32 Int64::High32() { return fSInt64.hi; }
- inline UInt32 Int64::Low32() { return fSInt64.lo; }
-
- //
- // Inlines
- //
-
- //----------------------------------------------------------------------------------------
- // Int64::FitsInLong:
- //
- // to legally crunch a signed 63 into a signed 31 bit number, the high 32 bits
- // must be only sign extension { zero or negative one }, and the high bit of the low
- // 32 bits must equal the sign, otherwise that 32nd bit is being used to store a
- // component of the value.
- //----------------------------------------------------------------------------------------
- inline Boolean Int64::FitsInLong() const
- {
- Boolean result = false; // assume large to be safe
-
- if (fSInt64.hi == 0) // could be a positive number,
- result = (*(SInt32*)&fSInt64.lo >= 0); // can it fit in 31 bits?
- else if (fSInt64.hi == -1) // could be a negative number
- result = (*(SInt32*)&fSInt64.lo < 0); // can it fit in 31 bits?
-
- // the high 32 bits was not a sign extension so this quantity can't fit in 32
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::FitsInUnsignedLong:
- //----------------------------------------------------------------------------------------
- inline Boolean Int64::FitsInUnsignedLong() const
- {
-
- //
- // if high 32 is a sign extension then true
- //
- // notice that wrapping around is made legal
- // I think that this is good, but I could be posessed by the devil
- // -Dave0
- //
- return (fSInt64.hi == 0) || (fSInt64.hi == -1);
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::=:
- //
- // WARNING: DO NOT declare an Int64 inside this method and assign another Int64 to it,
- // or you'll recurse forever. Me and Max, we've been there. Done that. -andy
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator =(const Int64& amount)
- {
- fSInt64.hi = amount.fSInt64.hi;
- fSInt64.lo = amount.fSInt64.lo;
-
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator =(int amount)
- {
- fSInt64.lo = amount;
- fSInt64.hi = 0;
-
- if (amount < 0)
- fSInt64.hi = -1;
-
- return *this;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator =(SInt32 amount)
- {
- fSInt64.lo = amount;
- fSInt64.hi = 0;
-
- if (amount < 0)
- fSInt64.hi = -1;
-
- return *this;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator =(UInt32 amount)
- {
- fSInt64.lo = amount;
- fSInt64.hi = 0;
-
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator =(SInt64 amount)
- {
- fSInt64.lo = amount.lo;
- fSInt64.hi = amount.hi;
-
- return *this;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64()
- {
- ;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64(int amount)
- {
- fSInt64.lo = amount;
- fSInt64.hi = 0;
-
- if (amount < 0)
- fSInt64.hi = -1;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64(SInt32 amount)
- {
- fSInt64.lo = amount;
- fSInt64.hi = 0;
-
- if (amount < 0)
- fSInt64.hi = -1;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64(UInt32 amount)
- {
- fSInt64.hi = 0;
- fSInt64.lo = amount;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64(UInt32 high,UInt32 low)
- {
- fSInt64.hi = high;
- fSInt64.lo = low;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::Int64:
- //----------------------------------------------------------------------------------------
- inline Int64::Int64(SInt64 amount)
- {
- fSInt64.hi = amount.hi;
- fSInt64.lo = amount.lo;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::SInt32:
- //----------------------------------------------------------------------------------------
- inline Int64::operator SInt32() const
- {
- if (FitsInLong())
- return fSInt64.lo;
- else
- return kInt64CanNotFitIn32Bits;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::UInt32:
- //----------------------------------------------------------------------------------------
- inline Int64::operator UInt32() const
- {
- if (FitsInUnsignedLong())
- return fSInt64.lo;
- else
- return kInt64CanNotFitIn32Bits;
- }
-
-
- //----------------------------------------------------------------------------------------
- // Int64::double:
- //----------------------------------------------------------------------------------------
- inline Int64::operator double() const
- {
- double result;
-
- result = fSInt64.hi;
- result *= 4294967296.0; // 2 ^ 32 (done on Tom's HP calculator, no less)
-
- result += double(fSInt64.lo);
-
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // Int64::+=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator +=(const Int64& amount)
- {
- Int64 result;
-
- result = Operation(opAddInt64, &amount);
- fSInt64.hi = result.High32();
- fSInt64.lo = result.Low32();
-
- return *this;
- } // Int64::+=
-
-
- //----------------------------------------------------------------------------------------
- // Int64::-=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator -=(const Int64& amount)
- {
- Int64 result;
-
- result = Operation(opSubtractInt64, &amount);
- fSInt64.hi = result.High32();
- fSInt64.lo = result.Low32();
-
- return *this;
- } // Int64::-=
-
-
- //----------------------------------------------------------------------------------------
- // Int64::>>=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator >>=(const Int64& amount)
- {
- Int64 result;
-
- result = Operation(opShiftRightInt64, &amount);
- fSInt64.hi = result.High32();
- fSInt64.lo = result.Low32();
-
- return *this;
- } // Int64::>>=
-
-
- //----------------------------------------------------------------------------------------
- // Int64::<<=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator <<=(const Int64& amount)
- {
- Int64 result;
-
- result = Operation(opShiftLeftInt64, &amount);
- fSInt64.hi = result.High32();
- fSInt64.lo = result.Low32();
-
- return *this;
- } // Int64::<<=
-
-
- //----------------------------------------------------------------------------------------
- // Int64::*=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator *=(const Int64& amount)
- {
- Int64 result;
-
- result = Operation(opMultiplyInt64, &amount);
- fSInt64.hi = result.High32();
- fSInt64.lo = result.Low32();
-
- return *this;
- } // Int64::*=
-
-
- //----------------------------------------------------------------------------------------
- // Int64::operator &=:
- //----------------------------------------------------------------------------------------
- inline Int64& Int64::operator &=(const Int64& amount)
- {
- fSInt64.hi = fSInt64.hi & amount.fSInt64.hi;
- fSInt64.lo = fSInt64.lo & amount.fSInt64.lo;
-
- return *this;
- }
-
-
- inline Int64 Int64::operator +(const Int64& amount) const { return Operation(opAddInt64, &amount); }
- inline Int64 Int64::operator -(const Int64& amount) const { return Operation(opSubtractInt64, &amount); }
- inline Int64 Int64::operator *(const Int64& amount) const { return Operation(opMultiplyInt64, &amount); }
- inline Int64 Int64::operator /(const Int64& amount) const { return Operation(opDivideInt64, &amount); }
- inline Int64 Int64::operator >>(const Int64& amount) const { return Operation(opShiftRightInt64, &amount); }
- inline Int64 Int64::operator <<(const Int64& amount) const { return Operation(opShiftLeftInt64, &amount); }
-
- inline Boolean Int64::operator !=(const Int64& b) const { return Comparison(cmpNotEqualInt64, &b); }
- inline Boolean Int64::operator ==(const Int64& b) const { return Comparison(cmpEqualInt64, &b); }
- inline Boolean Int64::operator >=(const Int64& b) const { return Comparison(cmpGreaterOrEqualInt64, &b); }
- inline Boolean Int64::operator <(const Int64& b) const { return Comparison(cmpLessInt64, &b); }
- inline Boolean Int64::operator <=(const Int64& b) const { return Comparison(cmpLessOrEqualInt64, &b); }
- inline Boolean Int64::operator >(const Int64& b) const { return Comparison(cmpGreaterInt64, &b); }
-
-
- #endif // REZ
- #endif // Int64_h
-